import g

"""接口参数检测"""


class Dict(dict):
    def __getattr__(self, key):
        return self.get(key, None)

    def __setattr__(self, key, value):
        self[key] = value


def chk_api_data(api_data, api_name):
    """
    接口定义参数使用：
        var: api中变量名
        type: 参数类型 bool(布尔类型) string(字符串) int(数字) float(浮点) dict(字典) list(列表) any(任意类型)
        desc: 参数说明
        needval: 指定参数值(必须是这个)
        needvalrange: 指定参数列表(必须在列表中)
        maxlen: string list dict最大长度
        minlen: string list dict最小长度
        maxnum: int float最大值
        minnum: int float最小值
        range: int float值范围
        xxx: 可传可不传的参数 只能配在最后一个参数 配了就不会检测
    以上字段组合使用
    """
    _res = {"s": 1}

    _clientData = api_data  # 客户端参数
    _chkApiData = g.m[api_name].getApiData()  # 接口定义参数
    _fmtApiData = {}  # 格式化之后的接口参数 dict

    # 特殊接口不做判断
    if api_name in [
        "api_chongzhi_pay",
        "bingo",
        "api_gm_addemail",
        "api_gm_sendsysmsg",
        "api_chat_tianyansetblack",
        "api_gm_tiren",
        "api_gm_tirenbyall",
        "api_gm_gonghui_changebase",
        "api_gm_clearchatdata"
    ]:
        _res["data"] = _clientData
        return _res

    # 不需要参数
    if not _chkApiData:
        _res["data"] = Dict(_fmtApiData)
        return _res

    """参数个数校验"""
    _xxxLen = len([1 for i in _chkApiData if "xxx" in i])
    _needLen = len(_chkApiData)
    # 参数个数应该为{1}个
    if _xxxLen <= 0 and len(_clientData) != _needLen:
        _res["s"] = -2
        _res["errmsg"] = g.L("error_len", _needLen)
        return _res

    """参数校验"""
    for idx, info in enumerate(_chkApiData):
        if "xxx" in info:
            try:
                _fmtApiData[info["var"]] = _clientData[idx]
            except:
                _fmtApiData[info["var"]] = None
            continue

        _chkVal = _clientData[idx]  # 客户端参数
        idx += 1  # 这里+=1是避免下标从0开始，给予的提示语容易误导
        _type = info["type"]  # 参数类型
        if _type != "any":
            _chkType = _type if _type != "string" else "str"
            # 第{1}参数类型应该为{1}
            if not isinstance(_chkVal, eval(_chkType)):
                _res["s"] = -3
                _res["errmsg"] = g.L("error_typeerror", idx, _type)
                return _res

        """参数值检测"""
        _needVal = info.get("needval")
        if _needVal is not None:
            # 第{1}个参数必须是{2}
            if _needVal != _chkVal:
                _res["s"] = -4
                _res["errmsg"] = g.L("error_needval", idx, _needVal)
                return _res

        _needValRange = info.get("needvalrange")
        if _needValRange is not None:
            # 第{1}个参数必须是在{2}中
            if _chkVal not in _needValRange:
                _res["s"] = -5
                _res["errmsg"] = g.L("error_needvalrange", idx, _needValRange)
                return _res

        """参数类型检测"""
        # bool类型检测
        if _type == "bool":
            # 第{1}个参数的类型应该是bool
            if not isinstance(_chkVal, bool):
                _res["s"] = -6
                _res["errmsg"] = g.L("error_bool", idx)
                return _res

        # string类型检测
        if _type in ["string", "str"]:
            # 第{1}个参数的类型应该是string
            if not isinstance(_chkVal, str):
                _res["s"] = -7
                _res["errmsg"] = g.L("error_string", idx)
                return _res

            # 最大长度检测
            _maxLen = info.get("maxlen")
            if _maxLen is not None:
                # 第{1}个参数的最大长度为{2}
                if len(_chkVal) > _maxLen:
                    _res["s"] = -8
                    _res["errmsg"] = g.L("error_maxlen", idx, _maxLen)
                    return _res

            # 最小长度检测
            _minLen = info.get("minlen")
            if _minLen is not None:
                # 第{1}个参数的最小长度为{2}
                if len(_chkVal) < _minLen:
                    _res["s"] = -9
                    _res["errmsg"] = g.L("error_minlen", idx, _minLen)
                    return _res

        # int、float类型检测
        elif _type in ["int", "float"]:
            # 第{1}个参数的类型应该是int
            if _type == "int" and not isinstance(_chkVal, int):
                _res["s"] = -10
                _res["errmsg"] = g.L("error_int", idx)
                return _res
            # 第{1}个参数的类型应该是float
            if _type == "float" and not isinstance(_chkVal, float):
                _res["s"] = -11
                _res["errmsg"] = g.L("error_float", idx)
                return _res

            # 范围检测
            _range = info.get("range")  # 范围
            if _range and len(_range) == 2:
                _min, _max = _range[0], _range[1]
                # 第{1}参数应该在{2}和{3}之间
                if not (_range[0] <= _chkVal <= _range[1]):
                    _res["s"] = -12
                    _res["errmsg"] = g.L("error_range", idx, _min, _max)
                    return _res

            # 最大值检测
            _maxNum = info.get("maxnum")
            if _maxNum is not None:
                # 第{1}个参数的最大值为{2}
                if _chkVal > _maxNum:
                    _res["s"] = -13
                    _res["errmsg"] = g.L("error_maxnum", idx, _maxNum)
                    return _res

            # 最小值检测
            _minNum = info.get("minnum")
            if _minNum is not None:
                # 第{1}个参数的最小值为{2}
                if _chkVal < _minNum:
                    _res["s"] = -14
                    _res["errmsg"] = g.L("error_minnum", idx, _minNum)
                    return _res

        # dict类型检测
        elif _type == "dict":
            # 最大长度检测
            _maxLen = info.get("maxlen")
            if _maxLen is not None:
                # 第{1}个参数的最大长度为{2}
                if len(_chkVal) > _maxLen:
                    _res["s"] = -15
                    _res["errmsg"] = g.L("error_maxlen", idx, _maxLen)
                    return _res

            # 最小长度检测
            _minLen = info.get("minlen")
            if _minLen is not None:
                # 第{1}个参数的最小长度为{2}
                if len(_chkVal) < _minLen:
                    _res["s"] = -16
                    _res["errmsg"] = g.L("error_minlen", idx, _minLen)
                    return _res

            for k, v in _chkVal.items():
                # dict的key必须是字符串
                if not isinstance(k, str):
                    _res["s"] = -17
                    _res["errmsg"] = g.L("error_dict_key_error", idx, _minLen)
                    return _res

        # list类型检测
        elif _type == "list":
            # 最大长度检测
            _maxLen = info.get("maxlen")
            if _maxLen is not None:
                # 第{1}个参数的最大长度为{2}
                if len(_chkVal) > _maxLen:
                    _res["s"] = -18
                    _res["errmsg"] = g.L("error_maxlen", idx, _maxLen)
                    return _res

            # 最小长度检测
            _minLen = info.get("minlen")
            if _minLen is not None:
                # 第{1}个参数的最小长度为{2}
                if len(_chkVal) < _minLen:
                    _res["s"] = -19
                    _res["errmsg"] = g.L("error_minlen", idx, _minLen)
                    return _res

        # 任意类型
        elif _type == "any":
            pass

        _fmtApiData[info["var"]] = _chkVal

    _res["data"] = Dict(_fmtApiData)

    return _res


if __name__ == '__main__':
    pass
